```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分布式系统安全架构实践 | Spring Cloud Gateway × Spring Security</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Helvetica Neue', Arial, sans-serif;
            color: #333;
            line-height: 1.8;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 700;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e48aa 0%, #9d50bb 100%);
        }
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            border-radius: 8px;
            overflow-x: auto;
        }
        .highlight-card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .highlight-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 15px 20px rgba(0, 0, 0, 0.1);
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(110,72,170,0.5) 50%, rgba(0,0,0,0) 100%);
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-6">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4">分布式系统安全架构实践</h1>
                    <p class="text-xl mb-8 opacity-90">基于Spring Cloud Gateway与Spring Security 6的安全解决方案</p>
                    <div class="flex space-x-4">
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-lg flex items-center">
                            <i class="fas fa-shield-alt mr-2"></i>
                            <span>认证鉴权</span>
                        </div>
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-lg flex items-center">
                            <i class="fas fa-project-diagram mr-2"></i>
                            <span>微服务架构</span>
                        </div>
                    </div>
                </div>
                <div class="md:w-1/2">
                    <div class="bg-white bg-opacity-10 p-6 rounded-xl backdrop-blur-sm">
                        <div class="mermaid">
                            graph LR
                            A[客户端] --> B[Spring Cloud Gateway]
                            B --> C[认证服务]
                            B --> D[课程服务]
                            B --> E[用户服务]
                            C --> F[(Redis)]
                            D --> G[(MySQL)]
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-5xl px-6 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg leading-relaxed mb-6 text-gray-700">
                分布式系统因其高扩展性和模块化设计被广泛应用，但认证与鉴权是关键挑战。Spring Cloud Gateway 提供动态路由和过滤功能，Spring Security 6 增强了安全控制，而 OAuth2 协议为分布式环境提供了标准化的令牌机制。
            </p>
        </section>

        <!-- Core Concepts -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 border-l-4 border-purple-600 pl-4">核心概念</h2>
            
            <div class="grid md:grid-cols-3 gap-8">
                <!-- Spring Cloud Gateway -->
                <div class="highlight-card bg-white p-6 rounded-lg">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-code-branch text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">1. Spring Cloud Gateway</h3>
                    <p class="text-gray-600">
                        Spring Cloud Gateway 是 Spring Cloud 生态中的 API 网关，负责请求路由、过滤、限流等功能。在分布式系统中，它作为统一入口，管理流量并验证令牌。
                    </p>
                </div>
                
                <!-- Spring Security 6 -->
                <div class="highlight-card bg-white p-6 rounded-lg">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-lock text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">2. Spring Security 6</h3>
                    <p class="text-gray-600">
                        Spring Security 6 提供强大的 OAuth2 集成，支持 JWT 解析和细粒度权限控制，适用于保护分布式资源服务。
                    </p>
                </div>
                
                <!-- OAuth2 -->
                <div class="highlight-card bg-white p-6 rounded-lg">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-key text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">3. OAuth2</h3>
                    <p class="text-gray-600">
                        OAuth2 是一种授权协议，支持密码模式、刷新令牌等，适用于分布式系统中的令牌管理。Access Token 用于访问资源，Refresh Token 用于续期。
                    </p>
                </div>
            </div>
        </section>

        <!-- System Architecture -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 border-l-4 border-purple-600 pl-4">系统架构设计</h2>
            
            <div class="bg-white rounded-lg p-6 mb-8">
                <p class="mb-4 text-gray-700">
                    系统由以下模块组成：
                </p>
                <ul class="list-disc pl-6 mb-6 text-gray-700">
                    <li class="mb-2"><strong>网关服务</strong>：基于 Spring Cloud Gateway，负责路由和令牌验证。</li>
                    <li class="mb-2"><strong>认证服务</strong>：Spring Security OAuth2 授权服务器，颁发 JWT 令牌。</li>
                    <li class="mb-2"><strong>资源服务</strong>：包括课程管理服务和用户服务，处理业务逻辑。</li>
                    <li class="mb-2"><strong>数据流</strong>：客户端通过网关登录，获取 JWT 令牌；网关验证令牌后路由请求到资源服务。</li>
                </ul>
                <div class="bg-gray-100 p-4 rounded-lg">
                    <p class="font-mono text-purple-700">
                        架构描述：<code>客户端 -> 网关 -> 认证服务/资源服务</code>
                    </p>
                </div>
            </div>
            
            <div class="bg-white p-6 rounded-lg">
                <div class="mermaid">
                    sequenceDiagram
                        participant Client
                        participant Gateway
                        participant AuthService
                        participant ResourceService
                        
                        Client->>Gateway: 登录请求
                        Gateway->>AuthService: 转发认证请求
                        AuthService-->>Gateway: 返回JWT令牌
                        Gateway-->>Client: 返回JWT令牌
                        
                        Client->>Gateway: 携带令牌访问资源
                        Gateway->>Gateway: 验证令牌
                        Gateway->>ResourceService: 转发请求
                        ResourceService-->>Gateway: 返回资源
                        Gateway-->>Client: 返回资源
                </div>
            </div>
        </section>

        <!-- Technology Stack -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 border-l-4 border-purple-600 pl-4">技术选型与环境准备</h2>
            
            <div class="grid md:grid-cols-2 gap-8 mb-10">
                <div>
                    <h3 class="text-xl font-bold mb-4 text-gray-700">技术栈</h3>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>Spring Boot 3.x</strong>：基础框架。</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>Spring Cloud 2022.x</strong>：网关与服务发现。</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>Spring Security 6.x</strong>：安全控制与 OAuth2 授权服务器。</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>Java 17</strong>：运行时环境。</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>工具</strong>：Maven（依赖管理）、MySQL（用户信息）、Redis（令牌存储）。</span>
                        </li>
                    </ul>
                </div>
                
                <div>
                    <h3 class="text-xl font-bold mb-4 text-gray-700">环境搭建</h3>
                    <ol class="list-decimal pl-6 space-y-3">
                        <li><strong>安装 Java 17</strong>：确保 JDK 17 已安装，运行 <code>java -version</code> 验证。</li>
                        <li><strong>安装 MySQL</strong>：创建数据库 <code>edu_platform</code>，用户 <code>root</code>，密码 <code>root</code>。</li>
                        <li><strong>安装 Redis</strong>：运行 Redis 容器（<code>docker run -p 6379:6379 redis:7.0</code>）。</li>
                        <li><strong>创建 Maven 项目</strong>：
                            <ul class="list-disc pl-6 mt-2">
                                <li>使用 IDE（如 IntelliJ IDEA）创建 Spring Boot 项目。</li>
                                <li>添加上述依赖到 <code>pom.xml</code>。</li>
                            </ul>
                        </li>
                    </ol>
                </div>
            </div>
            
            <div class="bg-white p-6 rounded-lg mb-10">
                <h4 class="text-xl font-bold mb-4 text-gray-700">项目结构</h4>
                <div class="font-mono bg-gray-100 p-4 rounded-lg">
                    <p>edu-platform/</p>
                    <p class="ml-4">├── gateway-service/</p>
                    <p class="ml-4">├── auth-service/</p>
                    <p class="ml-4">├── course-service/</p>
                    <p class="ml-4">└── user-service/</p>
                </div>
            </div>
            
            <div class="bg-white p-6 rounded-lg">
                <h4 class="text-xl font-bold mb-4 text-gray-700">初始化 MySQL 表</h4>
                <div class="code-block p-4 rounded-lg mb-4">
                    <pre><code class="language-sql">CREATE TABLE course (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);
INSERT INTO course (name) VALUES ('Java Programming'), ('Python Basics');</code></pre>
                </div>
            </div>
        </section>

        <!-- Practical Case -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 border-l-4 border-purple-600 pl-4">实战案例：在线教育平台</h2>
            
            <div class="bg-white rounded-lg p-6 mb-10">
                <h3 class="text-2xl font-bold mb-4 text-gray-700">1. 项目背景</h3>
                <p class="mb-4 text-gray-700">
                    这是一个在线教育平台，用户需登录后访问课程资源，教师可管理课程内容。需求包括：
                </p>
                <ul class="list-disc pl-6 text-gray-700">
                    <li class="mb-2">用户登录后获取访问令牌。</li>
                    <li class="mb-2">网关验证令牌并路由请求。</li>
                    <li class="mb-2">保护课程资源，仅限授权用户访问（学生读，教师读写）。</li>
                </ul>
            </div>
            
            <div class="bg-white rounded-lg p-6 mb-10">
                <h3 class="text-2xl font-bold mb-4 text-gray-700">2. 代码结构</h3>
                <p class="mb-4 text-gray-700">
                    项目模块：
                </p>
                <div class="grid md:grid-cols-2 gap-6">
                    <div>
                        <div class="bg-gray-100 p-4 rounded-lg mb-4">
                            <div class="flex items-center">
                                <i class="fas fa-server text-purple-500 mr-2"></i>
                                <span class="font-bold">gateway-service</span>
                            </div>
                            <p class="text-sm mt-1">网关，处理路由和令牌验证</p>
                        </div>
                        <div class="bg-gray-100 p-4 rounded-lg">
                            <div class="flex items-center">
                                <i class="fas fa-user-shield text-purple-500 mr-2"></i>
                                <span class="font-bold">auth-service</span>
                            </div>
                            <p class="text-sm mt-1">OAuth2 授权服务器，颁发 JWT</p>
                        </div>
                    </div>
                    <div>
                        <div class="bg-gray-100 p-4 rounded-lg mb-4">
                            <div class="flex items-center">
                                <i class="fas fa-book text-purple-500 mr-2"></i>
                                <span class="font-bold">course-service</span>
                            </div>
                            <p class="text-sm mt-1">课程管理，保护资源</p>
                        </div>
                        <div class="bg-gray-100 p-4 rounded-lg">
                            <div class="flex items-center">
                                <i class="fas fa-users text-purple-500 mr-2"></i>
                                <span class="font-bold">user-service</span>
                            </div>
                            <p class="text-sm mt-1">用户信息管理</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="bg-white rounded-lg p-6">
                <h3 class="text-2xl font-bold mb-6 text-gray-700">3. 实战步骤</h3>
                
                <!-- Step 1 -->
                <div class="mb-10 pb-10 border-b border-gray-200">
                    <h4 class="text-xl font-bold mb-4 text-gray-700">步骤 1：配置 OAuth2 授权服务器（auth-service）</h4>
                    <p class="mb-4 text-gray-700">
                        <strong>目标</strong>：搭建授权服务器，颁发 JWT 令牌，支持密码模式和刷新令牌。
                    </p>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-file-code text-purple-500 mr-2"></i>
                            创建项目
                        </h5>
                        <p class="mb-3 text-gray-700">
                            在 <code>auth-service</code> 模块中，添加 <code>pom.xml</code> 依赖：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-xml">&lt;!-- 示例依赖配置 --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
    &lt;artifactId&gt;spring-security-oauth2-authorization-server&lt;/artifactId&gt;
    &lt;version&gt;1.2.0&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-cog text-purple-500 mr-2"></i>
                            授权服务器配置
                        </h5>
                        <p class="mb-3 text-gray-700">
                            创建一个 <code>AuthorizationServerConfig</code> 类：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-java">@Configuration
public class AuthorizationServerConfig {
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId("edu-client")
                .clientSecret("{noop}secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.PASSWORD)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .scope("course:read")
                .scope("course:write")
                .build();
        return new InMemoryRegisteredClientRepository(client);
    }

    @Bean
    public JWKSource&lt;SecurityContext&gt; jwkSource() {
        KeyPair keyPair = generateRsaKey();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAKey rsaKey = new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID(UUID.randomUUID().toString())
                .build();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    }

    private KeyPair generateRsaKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            return keyPairGenerator.generateKeyPair();
        } catch (Exception ex) {
            throw new IllegalStateException("Failed to generate RSA key pair", ex);
        }
    }
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-user-lock text-purple-500 mr-2"></i>
                            用户认证配置
                        </h5>
                        <p class="mb-3 text-gray-700">
                            创建一个 <code>SecurityConfig</code> 类：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-java">@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .csrf(csrf -> csrf.disable());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails student = User.withUsername("student1")
                .password("{noop}123456")
                .authorities("ROLE_STUDENT", "SCOPE_course:read")
                .build();
        UserDetails teacher = User.withUsername("teacher1")
                .password("{noop}123456")
                .authorities("ROLE_TEACHER", "SCOPE_course:read", "SCOPE_course:write")
                .build();
        return new InMemoryUserDetailsManager(student, teacher);
    }
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-terminal text-purple-500 mr-2"></i>
                            客户端调用示例
                        </h5>
                        <p class="mb-3 text-gray-700">
                            使用 <code>curl</code> 获取 Access Token：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-2">
                            <pre><code class="language-bash">curl -X POST http://localhost:8081/oauth2/token \
-H "Authorization: Basic ZWR1LWNsaWVudDpzZWNyZXQ=" \
-d "grant_type=password&username=student1&password=123456&scope=course:read"</code></pre>
                        </div>
                        <p class="text-sm text-gray-500">
                            <i class="fas fa-info-circle mr-1"></i> <code>ZWR1LWNsaWVudDpzZWNyZXQ=</code> 是 <code>edu-client:secret</code> 的 Base64 编码
                        </p>
                    </div>
                    
                    <div class="bg-gray-100 p-4 rounded-lg">
                        <h5 class="font-bold mb-2 text-gray-700">响应示例</h5>
                        <div class="code-block p-4 rounded-lg">
                            <pre><code class="language-json">{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "xyz...",
  "scope": "course:read",
  "token_type": "Bearer",
  "expires_in": 3600
}</code></pre>
                        </div>
                    </div>
                </div>
                
                <!-- Step 2 -->
                <div class="mb-10 pb-10 border-b border-gray-200">
                    <h4 class="text-xl font-bold mb-4 text-gray-700">步骤 2：Spring Cloud Gateway 配置（gateway-service）</h4>
                    <p class="mb-4 text-gray-700">
                        <strong>目标</strong>：配置网关，验证 JWT 并路由请求到下游服务。
                    </p>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-file-code text-purple-500 mr-2"></i>
                            创建项目
                        </h5>
                        <p class="mb-3 text-gray-700">
                            在 <code>gateway-service</code> 模块中，添加 <code>pom.xml</code> 依赖：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-gateway&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-cog text-purple-500 mr-2"></i>
                            网关安全配置
                        </h5>
                        <p class="mb-3 text-gray-700">
                            创建一个 <code>GatewaySecurityConfig</code> 类：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-java">@Configuration
public class GatewaySecurityConfig {
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange()
            .pathMatchers("/oauth2/**").permitAll()
            .pathMatchers("/courses/**").authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt();
        return http.build();
    }
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-terminal text-purple-500 mr-2"></i>
                            客户端调用示例
                        </h5>
                        <p class="mb-3 text-gray-700">
                            假设客户端已获取 Access Token，访问课程资源：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-2">
                            <pre><code class="language-bash">curl -X GET http://localhost:8080/courses \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."</code></pre>
                        </div>
                    </div>
                    
                    <div class="bg-gray-100 p-4 rounded-lg">
                        <h5 class="font-bold mb-2 text-gray-700">成功响应示例</h5>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-json">[
  {"id": 1, "name": "Java Programming"},
  {"id": 2, "name": "Python Basics"}
]</code></pre>
                        </div>
                        
                        <h5 class="font-bold mb-2 text-gray-700">失败响应示例（无令牌）</h5>
                        <div class="code-block p-4 rounded-lg">
                            <pre><code class="language-json">{"status": 401, "error": "Unauthorized"}</code></pre>
                        </div>
                    </div>
                </div>
                
                <!-- Step 3 -->
                <div class="mb-10">
                    <h4 class="text-xl font-bold mb-4 text-gray-700">步骤 3：资源服务器（课程服务）配置（course-service）</h4>
                    <p class="mb-4 text-gray-700">
                        <strong>目标</strong>：保护课程资源，仅允许有 <code>course:read</code> 权限的用户访问。
                    </p>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-file-code text-purple-500 mr-2"></i>
                            创建项目
                        </h5>
                        <p class="mb-3 text-gray-700">
                            在 <code>course-service</code> 模块中，添加 <code>pom.xml</code> 依赖：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-oauth2-resource-server&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-cog text-purple-500 mr-2"></i>
                            安全配置
                        </h5>
                        <p class="mb-3 text-gray-700">
                            创建一个 <code>ResourceServerConfig</code> 类：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-java">@Configuration
public class ResourceServerConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/courses/**").hasAuthority("SCOPE_course:read")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
            );
        return http.build();
    }

    private JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(new CustomRoleConverter());
        return converter;
    }
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mb-6">
                        <h5 class="font-bold mb-2 text-gray-700 flex items-center">
                            <i class="fas fa-terminal text-purple-500 mr-2"></i>
                            客户端调用示例
                        </h5>
                        <p class="mb-3 text-gray-700">
                            获取课程列表（学生或教师）：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-2">
                            <pre><code class="language-bash">curl -X GET http://localhost:8080/courses \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."</code></pre>
                        </div>
                        
                        <p class="mb-3 text-gray-700 mt-4">
                            创建课程（仅教师）：
                        </p>
                        <div class="code-block p-4 rounded-lg mb-2">
                            <pre><code class="language-bash">curl -X POST http://localhost:8080/courses \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"name": "Spring Boot Advanced"}'</code></pre>
                        </div>
                    </div>
                    
                    <div class="bg-gray-100 p-4 rounded-lg">
                        <h5 class="font-bold mb-2 text-gray-700">成功响应示例</h5>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="language-json">{"id": 3, "name": "Spring Boot Advanced"}</code></pre>
                        </div>
                        
                        <h5 class="font-bold mb-2 text-gray-700">失败响应示例（学生无权限）</h5>
                        <div class="code-block p-4 rounded-lg">
                            <pre><code class="language-json">{"status": 403, "error": "Forbidden"}</code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```